<?php


namespace App\Http\Controllers\BE;


use App\Models\Periodical;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class PeriodicalMController
{

    public function detail()
    {
        $validator = validator(\request()->all(), [
            'id' => 'required|integer',
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }

        $id = \request('id');
        $periodical = Periodical::with([
            'directions:id,name',
            'included_databases:id,name',
            'audit_standard:id,name',
            'level:id,name',
            'cycle:id,name',
            'publication_time:id,name',
            'price:id,periodical_id,role_id,price',
            'price.role',
            'history',

        ])
            ->where('id', $id)
            ->first();

        if (is_null($periodical)) {
            return api_error('006');
        }
        return api_output($periodical);
    }

    public function updateDetail()
    {

        //todo:输入验证
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        DB::beginTransaction();
        try {
            $periodical = Periodical::where('id', request('id'))->first();
            $periodical->annex_info = request('annex_info');
            $periodical->audit_standard_id = request('audit_standard')['id'];
            $periodical->author_info = request('author_info');
            $periodical->char_count = request('char_count');
            $periodical->check_manuscript = request('check_manuscript');
            $periodical->column = request('column');
            $periodical->cover_core = request('cover_core');
            $periodical->cycle_id = request('cycle_id');
            $periodical->level_id = request('level')['id'];
            $periodical->domestic_number = request('domestic_number');
            $periodical->e_number = request('e_number');
            $periodical->impact_factor = request('impact_factor');
            $periodical->international_number = request('international_number');
            $periodical->invoice = request('invoice');
            $periodical->management = request('management');
            $periodical->name = request('name');
            $periodical->operator = auth()->id();
            $periodical->organizer = request('organizer');
            $periodical->page = request('page');
            $periodical->page_remark = request('page_remark');
            $periodical->post_code = request('post_code');
            $periodical->postcode = request('postcode');
            $publishcationDate = Carbon::parse(request('publishcation_date'));
            // $periodical->publication_date_m = $publishcationDate->month;
            // $periodical->publication_date_y = $publishcationDate->year;
            // $periodical->publication_time_id = request('publication_time')['id'];
            $periodical->references = request('references');
            $periodical->remark = request('remark');
            $periodical->review_difficulty = request('review_difficulty');
            $periodical->review_time = request('review_time');
            $periodical->science_periodical = request('science_periodical');
            $periodical->simple = request('simple');
            $periodical->summary_keywords = request('summary_keywords');
            $periodical->suspend_receiving = request('suspend_receiving');
            $periodical->recommend = request('recommend') ? 1 : 0;
            //更新上网情况
            DB::table('included_database_periodical')
                ->where('periodical_id', request('id'))
                ->delete();
            $includedDatabase = collect(request('included_databases'))->map(function ($item) {
                return [
                    'periodical_id' => request('id'),
                    'included_database_id' => $item
                ];
            });
            DB::table('included_database_periodical')
                ->insert($includedDatabase->toArray());
            //更新方向
            DB::table('direction_periodical')
                ->where('periodical_id', request('id'))
                ->delete();
            $direction = collect(request('directions'))->map(function ($item) {
                return [
                    'periodical_id' => request('id'),
                    'direction_id' => $item
                ];
            });
            DB::table('direction_periodical')
                ->insert($direction->toArray());
            //更新价格
            DB::table('periodical_prices')
                ->where('periodical_id', request('id'))
                ->delete();
            $sort_price = 0;    
            $price = collect(request('price'))->map(function ($item) use (&$sort_price) {
                if($item['role_id'] == 4){
                    $sort_price = $item['price'];
                }
                return [
                    'periodical_id' => request('id'),
                    'price' => $item['price'],
                    'role_id' => $item['role_id'],
                    'operator' => auth()->id(),
                    'created_at' => Carbon::now()
                ];
            });
            DB::table('periodicals')
                ->where('id', request('id'))
                ->update([
                    'sort_price' => $sort_price
                    ]);
            DB::table('periodical_prices')
                ->insert($price->toArray());
            $periodical->save();
            DB::commit();
            return api_output(true);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error($e->getMessage());
            return api_error('013');
        }


    }

    public function updateFile()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }
        $path = Storage::putFile('file', request()->file('file'));
        $periodical = Periodical::where('id', request('periodical'))->first();
        if (request('type') == 'letter') {
            $periodical->letter = \request()->root().'/storage/'.$path;
            $periodical->save();
        } else {
            $periodical->cover = \request()->root().'/storage/'.$path;
            $periodical->save();
        }
        return api_output($path);
    }

    public function history()
    {
        $id = request('id');
        $data = DB::table('publication_histories')
            ->where('periodical_id', $id)
            // ->orderByDesc('publish_at')
            // ->orderByDesc('publish_at_about')
            // 20220809 修改为内容开头的日期排序(就是当天填写资料的日期)
            ->orderByDesc('created_at')
            ->forPage(request('page'), request('limit'))
            ->get()
            ->map(function ($item) {
                return [
                    'id' => $item->id,
                    'content' => $item->content,
                    'publish_at' => date('Y-m',$item->publish_at),
                    'publish_at_about' => $item->publish_at_about,
                    'publish_at_about_name' => Db::table('publication_times')->where('id',$item->publish_at_about)->value('name')
                ];
            });

        $count = DB::table('publication_histories')
            ->where('periodical_id', $id)
            ->count();

        return api_output([
            'data' => $data,
            'count' => $count
        ]);
    }

    public function updateHistory()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }
        $id = request('id');
        $content = request('content');

        DB::table('publication_histories')
            ->where('id', $id)
            ->update([
                'content' => $content,
                'publish_at' => strtotime(request('publish_at'))+8*60*60,
                'publish_at_about' => request('publish_at_about'),
                'operator' => auth()->id(),
                'updated_at' => Carbon::now()
            ]);

        // 更新用来排序的缓存
        $periodical = DB::table('publication_histories')->where('id',$id)->orderBy('created_at','desc')->first();
        DB::table('periodicals')
            ->where('id',$periodical->periodical_id)
            ->update([
                'publication_date_m' => date('m',$periodical->publish_at),
                'publication_date_y' => date('Y',$periodical->publish_at),
                'publication_time_id' => $periodical->publish_at_about    
            ]);

        return api_output(true);
    }

    public function deleteHistory()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        DB::table('publication_histories')
            ->where('id', request('id'))
            ->delete();
        return api_output(true);
    }

    public function addHistory()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        DB::table('publication_histories')
            ->insert([
                'periodical_id' => request('id'),
                'content' => request('content'),
                'publish_at' => strtotime(request('publish_at'))+8*60*60,
                'publish_at_about' => request('publish_at_about'),
                'operator' => auth()->id(),
                'created_at' => Carbon::now()
            ]);
        
        // 更新用来排序的缓存
        DB::table('periodicals')
            ->where('id',request('id'))
            ->update([
                'publication_date_m' => date('m',strtotime(request('publish_at'))+8*60*60),
                'publication_date_y' => date('Y',strtotime(request('publish_at'))+8*60*60),
                'publication_time_id' => request('publish_at_about')    
            ]);

        return api_output(true);
    }

    public function delete()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        DB::table('periodicals')
            ->where('id', request('id'))
            ->delete();
        return api_output(true);
    }

    public function add()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        $validator = validator(\request()->all(), [
            'title' => 'required|string',
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }

        DB::beginTransaction();
        try {
            $id = DB::table('periodicals')
                ->insertGetId([
                    'name' => request('title')
                ]);
            $role = DB::table('roles')
                ->whereNotIn('id', [5, 6])
                ->get()
                ->map(function ($item) use ($id) {
                    return [
                        'periodical_id' => $id,
                        'price' => 0,
                        'role_id' => $item->id,
                        'operator' => auth()->id(),
                        'created_at' => Carbon::now()
                    ];
                });

            DB::table('periodical_prices')
                ->insert($role->toArray());
            DB::commit();
            return api_output([
                'id' => $id
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return api_error('013');
        }


    }

    public function getList()
    {
        $validator = validator(\request()->all(), [
            'keyword' => 'nullable|string',
            'page' => 'required|numeric',
            'limit' => 'required|numeric',
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }

        $keyword = \request('keyword');
        $page = \request('page');
        $limit = \request('limit');
        $suspend_receiving = \request('status');

        $query = Periodical::with([
            'directions:id,name',
            'included_databases:id,name',
            'audit_standard:id,name',
            'level:id,name',
            'cycle:id,name',
            'publication_time:id,name',
            'current:periodical_id,content',
            'price:id,periodical_id,role_id,price',
            'price.role',
            'history'
        ])
            ->when($keyword, function ($query, $keyword) {
                return $query->where('name', 'like', "%$keyword%");
            });

        if($suspend_receiving == '2'){
            $query->where('suspend_receiving',0);
        }
        if($suspend_receiving == '1'){
            $query->where('suspend_receiving',1);
        }

        $count = $query->count();

        $data = $query->forPage($page, $limit)
            ->orderBy('sort','desc')
            ->orderBy('publication_date_y','asc')
            ->orderBy('publication_date_m','asc')
            ->orderBy('publication_time_id','asc')
            ->get()
            ->map(function ($item) {
                $price_arr = $item->price->filter(function ($item) {
                    return $item->role_id <= auth()->user()->role_id;
                })->map(function ($item) {
                    return $item->role->show_title.":".$item->price;
                })
                ;
                $price_str = $item->price->filter(function ($item) {
                    return $item->role_id <= auth()->user()->role_id;
                })->map(function ($item) {
                    return $item->role->show_title.":".$item->price;
                })->implode(',');

                return [
                    'id' => $item->id,
                    'name' => $item->name,
                    'cover' => $item->cover,
                    'audit_standard_id' => $item->audit_standard_id,
                    'audit_standard' => $item->audit_standard->name ?? '',
                    'direction' => $item->directions->pluck('name') ?? '',
                    'level_id' => $item->level_id,
                    'level' => $item->level->name ?? '',
                    'cycle_id' => $item->cycle_id,
                    'cycle' => $item->cycle->name ?? '',
                    'date' => $item->publication_date_y.'-'.$item->publication_date_m,
                    'date_type_id' => $item->publication_time_id,
                    'date_type' => $item->publication_time->name ?? '',
                    'included_database' => $item->included_databases->pluck('name') ?? '',
                    'current' => $item->current->content ?? '',
                    'letter' => $item->letter,
                    'recommend' => $item->recommend,
                    'price' => $item->price,
                    'price_str' => $price_str,
                    'price_arr' => $price_arr,
                    'sort'=> $item->sort,
                    'suspend_receiving'=>$item->suspend_receiving
                ];
            });


        return api_output([
            'count' => $count,
            'data' => $data
        ]);
    }

    public function updatePrice()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        $id = request('id');
        $price = request('data');

        DB::beginTransaction();
        try {
            DB::table('periodical_prices')
                ->where('periodical_id', request('id'))
                ->delete();
            $sort_price = 0;
            $price = collect(request('data'))->map(function ($item) use (&$sort_price) {
                if($item['role_id'] == 4){
                    $sort_price = $item;
                }
                return [
                    'periodical_id' => request('id'),
                    'price' => $item['price'],
                    'role_id' => $item['role_id'],
                    'operator' => auth()->id(),
                    'created_at' => Carbon::now()
                ];
            });
            DB::table('periodicals')
                ->where('id', $sort_price['periodical_id'])
                ->update([
                    'sort_price' => $sort_price['price']
                    ]);
            DB::table('periodical_prices')
                ->insert($price->toArray());
            DB::commit();
            return api_output(true);
        } catch (\Exception $e) {
            Log::error('更新价格出错'.$e->getMessage());
            return api_error('013');
        }
    }
    
    public function updateStatus()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        $id = request('id');
        $status = request('status');

        DB::beginTransaction();
        try {
            DB::table('periodicals')
                ->where('id',$id)
                ->update(['suspend_receiving'=>$status]);
            
            DB::commit();
            return api_output(true);
        } catch (\Exception $e) {
            Log::error('更新出错'.$e->getMessage());
            return api_error('013');
        }
    }
    
    public function updateSort()
    {
        $user = auth()->user();
        if ($user->role_id !== 5 && $user->role_id !== 6) {
            return api_error('012');
        }

        $id = request('id');
        $sort = request('sort');

        DB::beginTransaction();
        try {
            DB::table('periodicals')
                ->where('id',$id)
                ->update(['sort'=>$sort]);
            
            DB::commit();
            return api_output(true);
        } catch (\Exception $e) {
            Log::error('更新排序出错'.$e->getMessage());
            return api_error('013');
        }
    }
}
